#include <iostream>
#include <string.h>     // 定义memset
#include <cassert>      // 定义assert
using std::cout;
using std::endl;
using std::ostream;
using std::string;

class sso_string{
public:
    // 构造函数与析构函数
    sso_string();
    sso_string(const char* pstr);
    ~sso_string();

    // 基础操作
    // sso_string(const char& rhs); // 类型写错了
    sso_string(const sso_string& rhs); // 类型写错了
    sso_string &operator=(const sso_string& rhs);
    friend ostream &operator<<(ostream &os, const sso_string& rhs);

    // 辅助函数
    const char* c_str() const;

private:
    union Buffer{
        char* _pointer;
        char _array[16];
    };
    Buffer _buffer;
    int _size;
};

sso_string::sso_string()
    :_size(0){
        memset(_buffer._array, 0, sizeof(_buffer._array));
    }

sso_string::sso_string(const char *pstr)
    :_size(strlen(pstr)){
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, pstr);
        }
        else{
            _buffer._pointer = new char[_size + 1]();    // 注意初始化，_size已经被赋值为strlen(pstr)
            strcpy(_buffer._pointer, pstr);
        }
    }

sso_string::sso_string(const sso_string &rhs)
    :_size(rhs._size){
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, rhs._buffer._array);
        }
        else{
            _buffer._pointer = new char[_size + 1]();    // 注意初始化，_size已经被赋值为strlen(pstr)
            strcpy(_buffer._pointer, rhs._buffer._pointer);
        }
    }

sso_string::~sso_string(){
    if(_size > 15){
        if(_buffer._pointer){
            delete [] _buffer._pointer;
            _buffer._pointer = nullptr;
        }
    }
}

sso_string& sso_string::operator=(const sso_string &rhs){
    if(this != &rhs){
        // 处理被赋值的字符串
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
        }else{
            delete []_buffer._pointer;
        }

        // 赋值
        if(rhs._size <= 15){
            strcpy(_buffer._array, rhs._buffer._array);
        }else{
            _buffer._pointer = new char[rhs._size + 1]();
            strcpy(_buffer._pointer, rhs._buffer._pointer);
        }
        _size = rhs._size;
    }

    return *this;
}

const char* sso_string::c_str() const{
    if(_size <= 15){
        return _buffer._array; 
    }else{
        return _buffer._pointer;
    }
}

void test_sso_copy() {
    // 测试短字符串拷贝（SSO模式）
    sso_string s1("short");
    sso_string s2 = s1; // 拷贝构造
    assert(strcmp(s2.c_str(), "short") == 0);

    // 测试长字符串拷贝（堆模式）
    sso_string s3("a_very_long_string_need_heap_allocation");
    sso_string s4 = s3; // 拷贝构造
    assert(strcmp(s4.c_str(), s3.c_str()) == 0);
    assert(s4.c_str() != s3.c_str()); // 验证深拷贝

    // 测试自我拷贝
    s4 = s4; // 自赋值安全
    assert(strcmp(s4.c_str(), s3.c_str()) == 0);
}

int main(){
    test_sso_copy();
    return 0;
}

